package com.liveims.webims;

import java.io.IOException;
import java.io.OutputStream;

import org.apache.log4j.Logger;

import com.liveims.webims.session.IMListener;
import com.liveims.webims.session.IMSAdapter;

import com.liveims.webims.session.PresenceListener;
import com.liveims.webims.util.WimsMessage;
import com.nextenso.proxylet.ProxyletConfig;
import com.nextenso.proxylet.ProxyletException;
import com.nextenso.proxylet.http.BufferedHttpRequestPushlet;
import com.nextenso.proxylet.http.HttpHeaders;
import com.nextenso.proxylet.http.HttpRequest;
import com.nextenso.proxylet.http.HttpRequestProlog;
import com.nextenso.proxylet.http.HttpResponse;

/*
 * The HTTP subscribe (to Message or Presence) Channel, through which the MESSAGE or PUBLISH will be pushed to client
 *
 */
public class Channel implements BufferedHttpRequestPushlet {
	
    private final static Logger log = Logger.getLogger(Channel.class);
    
	public int doRequest(HttpRequest request) throws ProxyletException {
		
		String sid = (String)request.getAttribute("sessionid");
		log.debug("get session id "+sid);
		
		request.getResponse().getProlog().setStatus(200);
		// Prepare a multipart response
	    try{
	       MultipartResponse multi = new MultipartResponse(request.getResponse());
           IMSAdapter imsAdapter = new IMSAdapter(sid);
           imsAdapter.addIMListener(multi);
           imsAdapter.addPresenceListener(multi);
           imsAdapter.activate();    
           log.debug("session listener is activated now");
	    }catch (Exception e){
	    	e.printStackTrace();
	    	log.error(e);
	    	request.getResponse().getProlog().setStatus(500);
	    }
	    
	    return BufferedHttpRequestPushlet.RESPOND_LAST_PROXYLET;
	}

	public int accept(HttpRequestProlog prolog, HttpHeaders headers) {
		log.info("request processing by Channel proxylet");
		return ACCEPT;
	}

	public void destroy() {
		// TODO Auto-generated method stub

	}

	public String getProxyletInfo() {
		// TODO Auto-generated method stub
		return null;
	}

	public void init(ProxyletConfig cnf) throws ProxyletException {
		// TODO Auto-generated method stub

	}
	
	public class MultipartResponse implements IMListener, PresenceListener {

		  HttpResponse res;
		  LineOutputStream out;
		  boolean endedLastResponse = true;
		  final static String END = "End";

		  public MultipartResponse(HttpResponse response) throws IOException {
		    // Save the response object and output stream
		    res = response;
		    out = new LineOutputStream(res.getBody().getOutputStream());
		    // Set things up
		    res.getHeaders().setContentType("multipart/x-mixed-replace;boundary="+END);		    
		    out.println();
		    out.println("--End");
		  }

		  public void startResponse(String contentType) throws IOException {
		    // End the last response if necessary
		    if (!endedLastResponse) {
		      endResponse();
		    }
		    // Start the next one
		    out.println("Content-Type: " + contentType);
		    out.println();
		    endedLastResponse = false;
		  }
          
		  public void endResponse() throws IOException {
		    // End the last response, and flush so the client sees the content
		    out.println();
		    out.println("--End");
		    out.flush();
		    endedLastResponse = true;
		  }

		  public void finish() throws IOException {
		    out.println("--End--");
		    out.flush();
		  }
		  
		  public void IMReceived(WimsMessage m) {
			 try{
				 startResponse(m.getContent_type());
				 out.println(m.getFrom());
				 out.println(m.getContent());
				 endResponse();
			 }catch(IOException e){
				 e.printStackTrace();
				 log.error("Can't send response, ", e);				 			 
			 }
				
		  }

		  public void NotifyReceived(WimsMessage m) {
			  try{
					 startResponse(m.getContent_type());
					 out.println(m.getFrom());
					 out.println(m.getContent());
					 endResponse();
				 }catch(IOException e){
					 e.printStackTrace();
					 log.error("Can't send response, ", e);				 			 
				 }			
		  }
		  
		  private class LineOutputStream {
			  public static final String CRLF = "\r\n";
			  OutputStream _o;
			  LineOutputStream(OutputStream o){ _o = o;	}
			  public void println() throws IOException{ _o.write(CRLF.getBytes());				  
			  }
			  public void println(String s) throws IOException{ _o.write((s+CRLF).getBytes());				  
			  }
			  public void flush() throws IOException{_o.flush();}
		  }
		}


}
